﻿// ------------------------------------------------------------------------
// 项目名称：Canroc.Net 
// 版权归属：Canroc（https://gitee.com/canroc）
//
// 许可证信息
// Canroc.Net项目主要遵循 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-APACHE 文件。
//
// 使用条款：
// 1.使用本项目应遵守相关法律法规和许可证的要求。
// 2.不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动。
// 3.任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任
//
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
//
// 其他重要信息
// Canroc.Net 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// ------------------------------------------------------------------------

using Canroc.Net.RemoteHttp.WeChat;
using Canroc.Net.RemoteHttp.WeChat.Dto;
using Canroc.Net.SystemService.RedisService;
using Canroc.Net.SystemService.WeChatService.Dto;
using System.Net;

namespace Canroc.Net.SystemService.WeChatService.Impl;

/// <summary>
///     微信服务
/// </summary>
public class WeChatService(
    IRedisService redisService,
    IWeChatRemoteHttp weChatHttp) : IWeChatService
{
    /// <summary>
    ///     发送模版消息
    /// </summary>
    /// <param name="data">消息信息</param>
    /// <returns></returns>
    public async Task<bool> SentTemplateMessageAsync(WeChatSentMessageInput data)
    {
        // 获取微信Token
        var weChatToken = await GetAccessTokenAsync();
        // 消息模版
        var officialOption = App.GetOptions<WeChatOfficialOptions>();
        var templateOption = officialOption.Template!.FirstOrDefault(t => t.Name == data.Template);
        _ = templateOption ?? throw Oops.Oh("未订阅此模版消息！");
        var noice = new WeChatOpenApiSendTemplateInput
        {
            Touser = data.Openid, TemplateId = templateOption.Key, Url = data.Url, Data = data.Message
        };

        // 发送
        var response = await weChatHttp.OfficialSendNoticeAsync(weChatToken, noice);
        return response is { StatusCode: HttpStatusCode.OK, Result.ErrCode: 0 }
            ? true
            : throw Oops.Oh(await response.ResponseMessage.Content.ReadAsStringAsync());
    }

    /// <summary>
    ///     获取微信Token
    /// </summary>
    /// <returns></returns>
    private async Task<string> GetAccessTokenAsync()
    {
        // 从缓存中获取Token
        var weChatAccessToken =
            await redisService.StringGetAsync<WeChatOpenApiAccessTokenOutput>("wechat-accesstoken");
        if (weChatAccessToken is not null) return weChatAccessToken.AccessToken;

        // 微信选项
        var officialOption = App.GetOptions<WeChatOfficialOptions>();
        // 获取微信Token
        var response = await weChatHttp.GetAccessTokenAsync(officialOption.AppId, officialOption.AppSecret);
        if (response.StatusCode != HttpStatusCode.OK || response.Result?.AccessToken == string.Empty)
        {
            throw Oops.Oh(await response.ResponseMessage.Content.ReadAsStringAsync());
        }

        // 设置缓存
        _ = await redisService.StringSetAsync("wechat-accesstoken", response.Result,
            TimeSpan.FromSeconds(response.Result!.ExpiresIn));
        weChatAccessToken = response.Result;

        return weChatAccessToken.AccessToken;
    }
}